package com.smartstate.iot.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.smartstate.iot.config.redis.RedisService;
import com.smartstate.iot.config.web.SpringUtils;
import com.smartstate.iot.entity.IotDataDistribution;
import com.smartstate.iot.entity.TopicConfig;
import com.smartstate.iot.entity.TopicLog;
import com.smartstate.iot.mapper.IotDataDistributionMapper;
import com.smartstate.iot.mapper.TopicLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 数据处理模块
 */
@Slf4j
public class ThreadService implements Runnable {

    @Resource
    RedisTemplate redisTemplate = RedisService.redis;

    String topic;
    String msg;

    public ThreadService(String topic, String msg) {
        this.topic = topic;
        this.msg = msg;
    }

    private String keys = "dataNumber";

    @Override
    public void run() {
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        if (msg.length() > 0) {
            Map<String, Object> parse = (Map) JSON.parse(msg);
            Object content = parse.get("content");
            JSONArray array = JSONArray.parseArray(content.toString());
            Map<String, Object> parse2 = new HashMap<>();
            for (Object o : array) {
                Map<String, Object> parse1 = (Map) JSON.parse(o.toString());
                String key = null;
                for (Map.Entry<String, Object> entry : parse1.entrySet()) {
                    key = entry.getKey();
                    int indexOf = key.indexOf(".");
                    String newKey = key.substring(indexOf + 1);
                    parse2.put(newKey, entry.getValue());
                }
                //  添加所属盒子ip
                String deviceId = (String) parse.get("deviceId");
                LambdaQueryWrapper<TopicConfig> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(TopicConfig::getDeviceId, deviceId);
                TopicService topicService = SpringUtils.getBean(TopicService.class);
                TopicConfig topicConfig = topicService.getOne(queryWrapper);
                parse2.put("ip", topicConfig.getIp());
                //  添加所属盒子状态
                TopicLogService logService = SpringUtils.getBean(TopicLogService.class);
                TopicLog topicLog = logService.getTypeByDeviceId(topicConfig.getDeviceId());
                parse2.put("type",topicLog.getType());
                //将数据放入缓存
                if (key != null) {
                    //TODO 这里需要根据key查询一下数据库中是否存在，存在只做更新不做覆盖/不存在就新增
                    int indexOf = key.indexOf(".");
                    String equipmentIdKey = key.substring(0, indexOf);
                    redisService.setCacheMap(parse.get("deviceId") + ":" + equipmentIdKey, parse2);
                    redisService.setCacheMap(equipmentIdKey, parse2);
                    log.info("设备数据保存成功！");
                }
                //  判断该数据是否被分发
                for (Map.Entry<String, Object> entry : parse1.entrySet()) {
                    key = entry.getKey();
                    String value1 = (String) entry.getValue();
                    handout(key, value1);
                }
            }
        }
    }

    /**
     * 递归跟新redis中的数据
     *
     * @param key
     * @param value
     */
    private void handout(String key, String value) {
        IotDataDistributionMapper dataDistributionMapper = SpringUtils.getBean(IotDataDistributionMapper.class);
        List<IotDataDistribution> mappings = dataDistributionMapper.getMapping(key);
        if (mappings.size() != 0) {
            RedisService redisService = SpringUtils.getBean(RedisService.class);
            HashMap<String, String> map = new HashMap<>();
            for (IotDataDistribution mapping : mappings) {
                double weight = mapping.getWeight();
                String targetKey = mapping.getDistributionTarget();
                //  TODO  修改数据分发
                int indexOf = targetKey.indexOf(".");
                String mapKey = targetKey.substring(indexOf + 1);
                String newValue = String.valueOf(Double.parseDouble(value) * weight);
                map.put(mapKey, newValue);
//                int index = key.indexOf(".");
                String hashKey = targetKey.substring(0, indexOf);
                //  缓存不带盒子的
                redisService.setCacheMap(hashKey, map);
                //  缓存带盒子的
                String boxKey = "";
                ArrayList<String> keys = getKeys();
                for (String s : keys) {
                    if (s.endsWith(hashKey)) {
                        boxKey = s;
                        break;
                    }
                }
                redisService.setCacheMap(boxKey, map);
                handout(targetKey, newValue);
            }
        }
    }

    /**
     * 获取redis中所有的key
     *
     * @return
     */
    private ArrayList<String> getKeys() {
        TopicLogMapper topicLogMapper = SpringUtils.getBean(TopicLogMapper.class);
        //  获取所有盒子
        List<TopicLog> topicLogs = topicLogMapper.getAllBox();
//        log.info(topicLogs.toString());
        TreeSet<String> boxName = new TreeSet<>();
        for (TopicLog topicLog : topicLogs) {
            boxName.add(topicLog.getDeviceId());
        }
        //  获取所有的key
        ArrayList<String> keys = new ArrayList<>();
        for (String logSet : boxName) {
            Set<String> tempKeys = redisTemplate.keys(logSet + ":*");
            if (tempKeys != null) {
                keys.addAll(tempKeys);
            }
        }
        return keys;
    }
}
